//
//  DateExt.swift
//  Swift-app开发基础架构
//
//  Created by pro on 2017/8/16.
//  Copyright © 2017年 com.itboye. All rights reserved.
//

import UIKit

extension Date {

    /// 默认时间格式 yyyy-MM-dd HH:mm:ss
    var defaultDateFormatter: DateFormatter {
    
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }
    static var defaultDateFormatter: DateFormatter {
        
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }
    
    
    /// 获取当前时间的时间戳
    ///
    /// - Returns: 时间戳
    func timestamp() -> TimeInterval {
        
        return self.timeIntervalSince1970
    }
    
    /// 返回当前时间的字符串表达
    ///
    /// - Parameter formatter: 时间表示格式
    /// - Returns: 字符串
    func string(formatter: DateFormatter?) -> String {
        
        if let fm = formatter {
            return fm.string(from: self)
        } else {
            return defaultDateFormatter.string(from: self)
        }
    }
    
    /// 默认格式下的时间当前时间字符串
    ///
    /// - Returns: 字符串
    func string() -> String {
        return string(formatter: nil)
    }
    
    /// 返回某个时间戳的字符串表达（类方法）
    ///
    /// - Parameters:
    ///   - stamp: 时间戳
    ///   - formatter: 格式
    /// - Returns: 字符串
    static func string(stamp: TimeInterval, formatter: DateFormatter?) -> String {
        
        let date = Date(timeIntervalSince1970: stamp)
        return date.string(formatter: formatter)
    }
    /// 同上
    ///
    /// - Parameter stamp: 时间戳
    /// - Returns: 字符串
    static func string(stamp: TimeInterval) -> String {
        
        let date = Date(timeIntervalSince1970: stamp)
        return date.string()
    }
    
    
    /// 获取当前日期的Components（和日期相关的年，月，日等数据）
    var dateComponents: DateComponents {

        let calendar = Calendar.current
        let components: Set<Calendar.Component> = [Calendar.Component.year, .month, .day, .hour, .minute, .second, .weekday]
        return calendar.dateComponents(components, from: self)
    }
//    /// 年份
//    var year: Int? {
//        return dateComponents.year
//    }
//    /// 月份
//    var month: Int? {
//        return dateComponents.month
//    }
//    /// 天
//    var day: Int? {
//        return dateComponents.day
//    }
    /// 周几(Int)
    var weekday: Int? {
        return dateComponents.weekday
    }
    /// 周几(String)
    private var weekdays: [String] { return ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] }
    var weekdayOfString: String? {
        if let w = weekday {
            return weekdays[w]
        } else {
            return nil
        }
    }
}

extension Date {
    
    /// String -> Date
    ///
    /// - Parameters:
    ///   - dateStr: date string
    ///   - formatter: date formatter
    /// - Returns: Date
    static func date(_ dateStr: String, formatter: String = "yyyy-MM-dd HH:mm:ss") -> Date? {
        
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = formatter
        dateFormatter.locale = Locale.current
        return dateFormatter.date(from: dateStr)
    }
    
    /// Date -> String
    ///
    /// - Parameter formatter: date formatter
    /// - Returns: date string
    func toString(_ formatter: String) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = formatter
        dateFormatter.locale = Locale.current
        return dateFormatter.string(from: self)
    }
}

extension Date {
    static func currentCalendar() -> Calendar {
        var sharedCalendar = Calendar(identifier: .gregorian)
        sharedCalendar.locale = Locale.current
        return sharedCalendar
    }
    
    /// Example: 2000/1/2 03:04:05 return 2000
    var year: Int {
        get {
            return Date.currentCalendar().component(.year, from: self)
        }
    }
    
    /// Example: 2000/1/2 03:04:05 return 1
    var month: Int {
        get {
            return Date.currentCalendar().component(.month, from: self)
        }
    }
    
    /// Example: 2000/1/2 03:04:05 return 2
    var day: Int {
        get {
            return Date.currentCalendar().component(.day, from: self)
        }
    }
    
    /// Example: 2000/1/2 03:04:05 return 3
    var hour: Int {
        get {
            return Date.currentCalendar().component(.hour, from: self)
        }
    }
    
    /// Example: 2000/1/2 03:04:05 return 4
    var minute: Int {
        get {
            return Date.currentCalendar().component(.minute, from: self)
        }
    }
    
    /// Example: 2000/1/2 03:04:05 return 5
    var second: Int {
        get {
            return Date.currentCalendar().component(.second, from: self)
        }
    }
}

extension Date {
    
    /// the same year
    ///
    /// - Parameter date: contrast time
    /// - Returns: true: equal; false: not equal
    func haveSameYear(_ date: Date) -> Bool {
        return self.year == date.year
    }
    
    func haveSameYearAndMonth(_ date: Date) -> Bool {
        return self.haveSameYear(date) && self.month == date.month
    }
    
    func haveSameYearMonthAndDay(_ date: Date) -> Bool {
        let components1 = Date.currentCalendar().dateComponents([.year, .month, .day], from: self)
        let components2 = Date.currentCalendar().dateComponents([.year, .month, .day], from: date)
        return components1 == components2
    }
    
    func haveSameYearMonthDayAndHour(_ date: Date) -> Bool {
        let components1 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour], from: self)
        let components2 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour], from: date)
        return components1 == components2
    }
    
    func haveSameYearMonthDayHourAndMinute(_ date: Date) -> Bool {
        let components1 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour, .minute], from: self)
        let components2 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour, .minute], from: date)
        return components1 == components2
    }
    
    func haveSameYearMonthDayHourMinuteAndSecond(_ date: Date) -> Bool {
        let components1 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
        let components2 = Date.currentCalendar().dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
        return components1 == components2
    }
}

extension Date {
    
    /// the number of days in the month
    ///
    /// - Returns: number of day
    func numberOfDaysInMonth() -> Int {
        if let range = Date.currentCalendar().range(of: .day, in: .month, for: self) {
            return range.count
        }
        
        return 0
    }
}
